home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
bench
/
dinomometer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
21KB
|
672 lines
/*
* Copyright (C) 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* dinomometer - a synthetic modeling benchmark for OpenGL by Mark Kilgard
* Silicon Graphics November 15, 1993 $Revision: 1.1 $
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <math.h> /* for cos(), sin(), and sqrt() */
#include <GL/gl.h>
#include <GL/glx.h> /* this includes the necessary X and gl.h
* headers */
#include <GL/glu.h> /* gluPerspective(), gluLookAt(), GLU polygon
* tesselator */
#include <X11/Xatom.h> /* for XA_RGB_DEFAULT_MAP atom */
#include <X11/Xmu/StdCmap.h> /* for XmuLookupStandardColormap() */
typedef enum {
RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE,
LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE, DINOSAUR
} displayLists;
void
hello(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
printf("%g, %g, %g, %g\n", angle, x, y, z);
}
Display *dpy;
Window win;
Pixmap pixmap;
GLXPixmap glxpixmap;
GC gc;
GLfloat angle = -150; /* in degrees */
GLboolean doubleBuffer = GL_TRUE, clear = GL_TRUE, verbose = GL_FALSE, immediate = GL_FALSE;
GLboolean direct = GL_TRUE, outline = GL_FALSE, backcull = GL_TRUE, lighting = GL_TRUE;
GLboolean usePixmap = GL_FALSE, finePrint = GL_TRUE;
int X = 10, Y = 10, W = 300, H = 300, duration = 10, totalPolys = 0;
int reps = 1;
XSizeHints sizeHints =
{0};
GLdouble bodyWidth = 2.0;
GLenum primativeType;
int vertices, numPolys;
char revision[15], version[15];
int configuration[] =
{GLX_DOUBLEBUFFER, GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
GLfloat body[][2] =
{
{0, 3},
{1, 1},
{5, 1},
{8, 4},
{10, 4},
{11, 5},
{11, 11.5},
{13, 12},
{13, 13},
{10, 13.5},
{13, 14},
{13, 15},
{11, 16},
{8, 16},
{7, 15},
{7, 13},
{8, 12},
{7, 11},
{6, 6},
{4, 3},
{3, 2},
{1, 2}};
GLfloat arm[][2] =
{
{8, 10},
{9, 9},
{10, 9},
{13, 8},
{14, 9},
{16, 9},
{15, 9.5},
{16, 10},
{15, 10},
{15.5, 11},
{14.5, 10},
{14, 11},
{14, 10},
{13, 9},
{11, 11},
{9, 11}};
GLfloat leg[][2] =
{
{8, 6},
{8, 4},
{9, 3},
{9, 2},
{8, 1},
{8, 0.5},
{9, 0},
{12, 0},
{10, 1},
{10, 2},
{12, 4},
{11, 6},
{10, 7},
{9, 7}};
GLfloat eye[][2] =
{
{8.75, 15},
{9, 14.7},
{9.6, 14.7},
{10.1, 15},
{9.6, 15.25},
{9, 15.25}};
GLfloat lightZeroPosition[] =
{10.0, 4.0, 10.0, 1.0};
GLfloat lightZeroColor[] =
{0.8, 1.0, 0.8, 1.0}; /* green-tinted */
GLfloat lightOnePosition[] =
{-1.0, -2.0, 1.0, 0.0};
GLfloat lightOneColor[] =
{0.6, 0.3, 0.2, 1.0}; /* red-tinted */
GLfloat skinColor[] =
{0.1, 1.0, 0.1, 1.0}, eyeColor[] =
{1.0, 0.2, 0.2, 1.0};
char *drawable;
#include "immediate.c"
#define DoLighting
#include "immediate.c"
#undef DoLighting
void
fatalError(char *message)
{
fprintf(stderr, "glxdino: %s\n", message);
exit(1);
}
Colormap
getColormap(XVisualInfo * vi)
{
Status status;
XStandardColormap *standardCmaps;
Colormap cmap;
int i, numCmaps;
/* be lazy; using DirectColor too involved for this example */
if (vi->class != TrueColor)
fatalError("no support for non-TrueColor visual");
/* if no standard colormap but TrueColor, just make an unshared one */
status = XmuLookupStandardColormap(dpy, vi->screen, vi->visualid,
vi->depth, XA_RGB_DEFAULT_MAP, /* replace */ False, /* retain */ True);
if (status == 1) {
status = XGetRGBColormaps(dpy, RootWindow(dpy, vi->screen),
&standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP);
if (status == 1)
for (i = 0; i < numCmaps; i++)
if (standardCmaps[i].visualid == vi->visualid) {
cmap = standardCmaps[i].colormap;
XFree(standardCmaps);
return cmap;
}
}
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
return cmap;
}
/* #define GenerateImmediateModeCode /* */
#ifdef GenerateImmediateModeCode
#define CodeGen(msg) printf("%s\n", msg);
#define CodeGen3(msg,x,y,z) printf(msg,x,y,z);
#else
#define CodeGen(msg)
#define CodeGen3(msg,x,y,z)
#endif
static void
myBegin(GLenum type)
{
primativeType = type;
vertices = 0;
glBegin(type);
#ifdef GenerateImmediateModeCode
switch (type) {
case GL_TRIANGLE_FAN:
printf("glBegin(GL_TRIANGLE_FAN);\n");
break;
case GL_TRIANGLE_STRIP:
printf("glBegin(GL_TRIANGLE_STRIP);\n");
break;
case GL_TRIANGLES:
printf("glBegin(GL_TRIANGLES);\n");
break;
default:
printf("ERROR\n");
}
#endif
}
static void
myVertex(GLfloat * vertex)
{
vertices++;
glVertex2fv(vertex); /* semi-tricky */
#ifdef GenerateImmediateModeCode
printf("glVertex2f(%g,%g);\n", vertex[0], vertex[1]);
#endif
}
static void
myEnd()
{
switch (primativeType) {
case GL_TRIANGLE_FAN:
case GL_TRIANGLE_STRIP:
numPolys += vertices - 2;
break;
case GL_TRIANGLES:
numPolys += vertices / 3;
break;
}
glEnd();
#ifdef GenerateImmediateModeCode
printf("glEnd();\n");
#endif
}
int
extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, GLdouble thickness, GLuint side,
GLuint edge, GLuint whole)
{
static GLUtriangulatorObj *tobj = NULL;
GLdouble vertex[3], dx, dy, len;
int i;
int count = dataSize / (2 * sizeof(GLfloat));
if (tobj == NULL) {
tobj = gluNewTess(); /* create and initialize a GLU polygon
* tesselation object */
gluTessCallback(tobj, GLU_BEGIN, myBegin);
gluTessCallback(tobj, GLU_VERTEX, myVertex);
gluTessCallback(tobj, GLU_END, myEnd);
}
CodeGen("/* side */");
glNewList(side, GL_COMPILE);
CodeGen("glShadeModel(GL_SMOOTH);");
glShadeModel(GL_SMOOTH); /* smooth shade minimizes seeing tessellation */
numPolys = 0;
gluBeginPolygon(tobj);
for (i = 0; i < count; i++) {
vertex[0] = data[i][0];
vertex[1] = data[i][1];
vertex[2] = 0;
gluTessVertex(tobj, vertex, &data[i]);
}
gluEndPolygon(tobj);
glEndList();
CodeGen("/* edge */");
glNewList(edge, GL_COMPILE);
CodeGen("glShadeModel(GL_FLAT);");
glShadeModel(GL_FLAT); /* flat shade keeps angular hands from being
* "smoothed" */
CodeGen("glBegin(GL_QUAD_STRIP);");
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= count; i++) { /* mod function handles closing the
* edge */
glVertex3f(data[i % count][0], data[i % count][1], 0.0);
CodeGen3("glVertex3f(%g,%g,%g);\n", data[i % count][0], data[i % count][1], 0.0);
/*
* Calculate a unit normal by dividing by Euclidean distance. We
* could be lazy and use glEnable(GL_NORMALIZE) so we could pass in
* arbitrary normals for a very slight performance hit.
*/
dx = data[(i + 1) % count][1] - data[i % count][1];
dy = data[i % count][0] - data[(i + 1) % count][0];
len = sqrt(dx * dx + dy * dy);
if (lighting) {
glNormal3f(dx / len, dy / len, 0.0); /* last normal is
* extraneous */
CodeGen3("glNormal3f(%g,%g,%g);\n", dx / len, dy / len, 0.0);
}
glVertex3f(data[i % count][0], data[i % count][1], thickness);
CodeGen3("glVertex3f(%g,%g,%g);\n", data[i % count][0], data[i % count][1], thickness);
}
CodeGen("glEnd();");
glEnd();
glEndList();
CodeGen("/* whole solid */");
glNewList(whole, GL_COMPILE);
CodeGen("glFrontFace(GL_CW);");
if (backcull)
glFrontFace(GL_CW);
CodeGen("/* call edge routine */");
glCallList(edge);
CodeGen("glNormal3f(0.0, 0.0, -1.0);");
if (lighting)
glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */
CodeGen("/* call side routine */");
glCallList(side);
CodeGen("glPushMatrix();");
glPushMatrix();
CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, thickness);
glTranslatef(0.0, 0.0, thickness);
CodeGen("glFrontFace(GL_CCW);");
if (backcull)
glFrontFace(GL_CCW);
CodeGen("glNormal3f(0.0, 0.0, 1.0);");
if (lighting)
glNormal3f(0.0, 0.0, 1.0); /* opposite constant normal for other
* side */
CodeGen("/* call side routine */");
glCallList(side);
CodeGen("glPopMatrix();");
glPopMatrix();
glEndList();
return numPolys * 2 + count + 1;
}
int
makeDinosaur(void)
{
GLfloat bodyWidth = 3.0;
int bodyPolys, armPolys, legPolys, eyePolys;
CodeGen("/* the body */");
bodyPolys = extrudeSolidFromPolygon(body, sizeof(body), bodyWidth,
BODY_SIDE, BODY_EDGE, BODY_WHOLE);
CodeGen("/* an arm */");
armPolys = extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4,
ARM_SIDE, ARM_EDGE, ARM_WHOLE);
CodeGen("/* a leg */");
legPolys = extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2,
LEG_SIDE, LEG_EDGE, LEG_WHOLE);
CodeGen("/* the eyes */");
eyePolys = extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2,
EYE_SIDE, EYE_EDGE, EYE_WHOLE);
glNewList(DINOSAUR, GL_COMPILE);
CodeGen("glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);");
glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
glCallList(BODY_WHOLE);
CodeGen("glPushMatrix();");
glPushMatrix();
CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, bodyWidth);
glTranslatef(0.0, 0.0, bodyWidth);
CodeGen("/* call arm routine */");
glCallList(ARM_WHOLE);
CodeGen("/* call leg routine */");
glCallList(LEG_WHOLE);
CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, -bodyWidth - bodyWidth / 4);
glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4);
CodeGen("/* call arm routine */");
glCallList(ARM_WHOLE);
CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, -bodyWidth / 4);
glTranslatef(0.0, 0.0, -bodyWidth / 4);
CodeGen("/* call leg routine */");
glCallList(LEG_WHOLE);
CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, bodyWidth / 2 - 0.1);
glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1);
CodeGen("glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);");
glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
CodeGen("/* call eye routine */");
glCallList(EYE_WHOLE);
CodeGen("glPopMatrix();");
glPopMatrix();
glEndList();
return bodyPolys + armPolys * 2 + legPolys * 2 + eyePolys * 2;
}
void
main(int argc, char **argv)
{
XVisualInfo *vi;
Colormap cmap;
XSetWindowAttributes swa;
GLXContext cx;
char *display = NULL, *geometry = NULL;
int flags, i, n, depthBufferDepth, dinoRenders, warmup;
float elapsed;
struct timeval beginTime, finishTime;
/*** (1) process normal X command line arguments ***/
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-geometry")) {
i++;
if (i >= argc)
fatalError("follow -geometry option with geometry parameter");
geometry = argv[i];
} else if (!strcmp(argv[i], "-display")) {
i++;
if (i >= argc)
fatalError("follow -display option with display parameter");
display = argv[i];
} else if (!strcmp(argv[i], "-time")) {
i++;
if (i >= argc)
fatalError("follow -time option with seconds to run");
duration = atoi(argv[i]);
} else if (!strcmp(argv[i], "-repeat")) {
i++;
if (i >= argc)
fatalError("follow -repeat option with repeat count");
reps = atoi(argv[i]);
} else if (!strcmp(argv[i], "-single"))
doubleBuffer = GL_FALSE;
else if (!strcmp(argv[i], "-noclear"))
clear = GL_FALSE;
else if (!strcmp(argv[i], "-indirect"))
direct = GL_FALSE;
else if (!strcmp(argv[i], "-outline"))
outline = GL_TRUE;
else if (!strcmp(argv[i], "-nocull"))
backcull = GL_FALSE;
else if (!strcmp(argv[i], "-nolight"))
lighting = GL_FALSE;
else if (!strcmp(argv[i], "-immediate"))
immediate = GL_TRUE;
else if (!strcmp(argv[i], "-pixmap"))
usePixmap = GL_TRUE;
else if (!strcmp(argv[i], "-nofineprint"))
finePrint = GL_FALSE;
else if (!strcmp(argv[i], "-verbose"))
verbose = GL_TRUE;
else {
printf("\ndinomometer options:\n");
printf(" -display str X display, str is display name\n");
printf(" -geometry #x# window size, WxH+X+Y\n");
printf(" -time # time to run test, followed by # in seconds\n");
printf(" -repeat # number of iternations to run\n");
printf(" -single single buffered (default: double buffered if available)\n");
printf(" -noclear skip depth and image buffer clear per dino\n");
printf(" -indirect indirect rendering (default: direct if available)\n");
printf(" -outline outlines of polygons (default: filled)\n");
printf(" -nocull disable back face culling (default: enabled\n");
printf(" -nolight disable lighting and normals (default: enabled\n");
printf(" -nofineprint don't print all the fine print info\n");
printf(" -pixmap render into pixmaps (forces indirect)\n");
printf(" -verbose print warmup estimate info\n\n");
exit(1);
}
}
/*** (2) open a connection to the X server ***/
dpy = XOpenDisplay(display);
if (dpy == NULL)
fatalError("could not open display");
/*** (3) make sure OpenGL's GLX extension supported ***/
if (!glXQueryExtension(dpy, NULL, NULL))
fatalError("X server has no OpenGL GLX extension");
/*** (4) find an appropriate visual and a colormap for it ***/
/* find an OpenGL-capable RGB visual with depth buffer */
if (!doubleBuffer)
goto SingleBufferOverride;
vi = glXChooseVisual(dpy, DefaultScreen(dpy), configuration);
if (vi == NULL) {
SingleBufferOverride:
vi = glXChooseVisual(dpy, DefaultScreen(dpy), &configuration[1]);
if (vi == NULL)
fatalError("no appropriate RGB visual with depth buffer");
doubleBuffer = GL_FALSE;
}
cmap = getColormap(vi);
/*** (5) create an OpenGL rendering context ***/
/* create an OpenGL rendering context */
if (usePixmap)
direct = GL_FALSE;
cx = glXCreateContext(dpy, vi, /* no sharing of display lists */ NULL,
/* direct rendering if possible */ direct);
if (cx == NULL)
fatalError("could not create rendering context");
/*** (6) create an X window with the selected visual and right properties ***/
flags = XParseGeometry(geometry, &X, &Y, (unsigned int *) &W, (unsigned int *) &H);
if (XValue & flags) {
if (XNegative & flags)
X = DisplayWidth(dpy, DefaultScreen(dpy)) + X - sizeHints.width;
}
if (YValue & flags) {
if (YNegative & flags)
Y = DisplayHeight(dpy, DefaultScreen(dpy)) + Y - sizeHints.height;
}
swa.colormap = cmap;
swa.border_pixel = 0;
swa.override_redirect = True;
win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), X, Y, W, H,
0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWOverrideRedirect, &swa);
if (usePixmap) {
XGCValues gcval;
pixmap = XCreatePixmap(dpy, win, W, H, vi->depth);
glxpixmap = glXCreateGLXPixmap(dpy, vi, pixmap);
gcval.graphics_exposures = 0;
gc = XCreateGC(dpy, pixmap, GCGraphicsExposures, &gcval);
}
/*** (7) bind the rendering context to the window ***/
if (!usePixmap) {
glXMakeCurrent(dpy, win, cx);
} else {
glXMakeCurrent(dpy, glxpixmap, cx);
}
/*** (8) make the desired display lists ***/
totalPolys = makeDinosaur();
/*** (9) configure the OpenGL context for rendering ***/
glViewport(0, 0, W, H); /* XXX workaround Reality Engine bug */
if (backcull)
glEnable(GL_CULL_FACE); /* ~50% better perfomance than no back-face
* culling on Entry Indigo */
glEnable(GL_DEPTH_TEST); /* enable depth buffering */
if (lighting)
glEnable(GL_LIGHTING); /* enable lighting */
glMatrixMode(GL_PROJECTION);/* set up projection transform */
gluPerspective( /* field of view in degree */ 40.0, /* aspect ratio */ 1.0,
/* Z near */ 1.0, /* Z far */ 40.0);
glMatrixMode(GL_MODELVIEW); /* now change to modelview */
gluLookAt(0.0, 0.0, 30.0, /* eye is at (0,0,30) */
0.0, 0.0, 0.0, /* center is at (0,0,0) */
0.0, 1.0, 0.); /* up is in postivie Y direction */
glPushMatrix(); /* dummy push so we can pop on model recalc */
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
glLightfv(GL_LIGHT1, GL_POSITION, lightOnePosition);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightOneColor);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1); /* enable both lights */
if (outline)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawBuffer(GL_FRONT);
/*** (10) request the X window to be displayed on the screen ***/
XMapWindow(dpy, win);
XInstallColormap(dpy, cmap);
glXWaitX();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#define RENDER(how) \
glPopMatrix(); \
glPushMatrix(); \
glRotatef(angle, 0.0, 1.0, 0.0); \
glTranslatef(-8, -8, -bodyWidth / 2); \
if(clear) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); \
how; \
angle -= 60.12345; /* full rotation every 6 frames gives more
* fair workload */
if (usePixmap) {
warmup = 15 + duration / 3;
} else {
warmup = glXIsDirect(dpy, cx) ? 30 : 30 + duration * 3;
}
if (verbose) {
printf("\nDoing %d warm ups...", warmup);
fflush(stdout);
}
gettimeofday(&beginTime);
if (immediate) {
if (lighting) {
for (i = 0; i < warmup; i++) {
RENDER(renderDinosaur())
}
} else {
for (i = 0; i < warmup; i++) {
RENDER(renderDinosaurNoLite())
}
}
} else {
for (i = 0; i < warmup; i++) {
RENDER(glCallList(DINOSAUR));
}
}
glFinish();
gettimeofday(&finishTime);
if (finishTime.tv_usec < beginTime.tv_usec) {
finishTime.tv_usec += 1000000;
finishTime.tv_sec -= 1;
}
elapsed = (float) (finishTime.tv_usec - beginTime.tv_usec) / 1000000.0 +
(float) (finishTime.tv_sec - beginTime.tv_sec);
if (verbose)
printf(" estimated rate = %g dinos/second\n", (float) warmup / elapsed);
if (usePixmap) {
if (verbose)
printf("\nShowing pixmap.\n");
XCopyArea(dpy, pixmap, win, gc, 0, 0, W, H, 0, 0);
XSync(dpy, 0);
}
dinoRenders = (float) warmup / elapsed * duration;
if (dinoRenders < 18)
dinoRenders = 18; /* always do at least 18 */
/*** (11) begin iterations ***/
sscanf("$Revision: 1.1 $", "%s %s $", revision, version);
printf("\nOpenGL Dinomometer (version %s)\n\n", version);
for (n = 0; n < reps; n++) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gettimeofday(&beginTime);
if (immediate) {
if (lighting) {
for (i = 0; i < dinoRenders; i++) {
RENDER(renderDinosaur())
}
} else {
for (i = 0; i < dinoRenders; i++) {
RENDER(renderDinosaurNoLite())
}
}
} else {
for (i = 0; i < dinoRenders; i++) {
RENDER(glCallList(DINOSAUR))
}
}
glFinish();
gettimeofday(&finishTime);
if (finishTime.tv_usec < beginTime.tv_usec) {
finishTime.tv_usec += 1000000;
finishTime.tv_sec -= 1;
}
elapsed = (float) (finishTime.tv_usec - beginTime.tv_usec) / 1000000.0 +
(float) (finishTime.tv_sec - beginTime.tv_sec);
printf("FlyntStones: %g dinos/second\n", (float) dinoRenders / elapsed);
printf(" %g polys/second\n\n", (float) totalPolys * dinoRenders / elapsed);
}
drawable = usePixmap ? "pixmap" : "window";
if (finePrint) {
printf("THE FINE PRINT: %s depth %d bits/pixel, %d polys/dino,\n",
drawable, vi->depth, totalPolys);
printf("back-face culling %s, polygon mode is %s, lighting %s,\n",
backcull ? "on" : "off",
outline ? "line" : "filled",
lighting ? "on" : "off");
printf("%d dinos rendered, rendering is %s, vendor is\n",
dinoRenders, glXIsDirect(dpy, cx) ? "direct" : "indirect");
glGetIntegerv(GL_DEPTH_BITS, &depthBufferDepth);
printf("%s, renderer is %s, version is %s, %d bits of depth\n",
glGetString(GL_VENDOR), glGetString(GL_RENDERER),
glGetString(GL_VERSION), depthBufferDepth);
printf("buffer, %d pixel %s width, %d pixel %s height,\n",
W, drawable, H, drawable);
printf("using %s, spent %g actual seconds\n",
immediate ? "immediate mode" : "display lists",
elapsed);
printf("benchmarking.\n\n");
}
exit(0);
}